import Vue from 'vue'
import '../assets/fonts/iconfont.css'
import Annotation from './index.vue'
import Markup from '../utils/markup'

let _AnnotationConstructor

let _isinit = false

const defaultConfigs = {
  showToolbar: true,

  screenBasePoint: {
    x: 0,
    y: 0
  },
  absBasePoint: {
    x: 0,
    y: 0
  },
  zoomFactor: {
    x: 1,
    y: 1
  }
}

const shapeKey = {
  duoxuanweixuanzhong: 1,
  danxuanweixuan: 2,
  guanbi1: 3,
  yunduo: 4,
  zhiduwenben: 5,
  'changjiantou-shang': 6
}

const defaultStyle = {
  // '#f8e71c', '#f58a23', '#5c5c5c',
  // colors: ["#d0021b", "#ed4dad", "#2b84ed", "#7ed321", "#000000", "#ffffff"],
  colors: ['#d0021b', '#f5a623', '#4a90e2', '#7ed321'],
  defaultColor: false,

  defaultLineWidth: false,
  lineWidth: [3, 8, 12],

  defaultShape: false,
  shape: ['changjiantou-shang', 'yunduo', 'duoxuanweixuanzhong', 'danxuanweixuan', 'guanbi1', 'zhiduwenben'],

  defaultFontSize: false,
  fontSize: [12, 14, 18, 24],

  style: {
    'stroke-width': 3,
    'stroke-color': '#d0021b',
    'stroke-opacity': 1.0,
    'fill-color': '#d0021b',
    'fill-opacity': 0.0,
    'font-family': 'Arial',
    'font-size': 16,
    'font-style': '', // 'italic'
    'font-weight': '' // 'bold'
  }
}

function index(el, params, callback) {
  if (!el) return console.error('未找到标注盒子元素')

  el = typeof el === 'string' ? document.querySelector(el) : el

  if (!_isinit) {
    if (!_AnnotationConstructor) {
      _AnnotationConstructor = Vue.extend(Annotation)
    }
    _isinit = true
  }
  this._init(params, el)

  return this
}

index.prototype = index.prototype || {}

index.prototype._init = function (params, el) {
  // 默认参数处理
  params = params || {}
  let toolConfigs = params.toolConfigs || {}
  if (!toolConfigs.defaultShape) {
    toolConfigs.defaultShape = toolConfigs.shape ? toolConfigs.shape[0] : defaultStyle.shape[0]
  }

  if (!toolConfigs.defaultColor) {
    toolConfigs.defaultColor = toolConfigs.colors ? toolConfigs.colors[0] : defaultStyle.colors[0]
  }
  if (!toolConfigs.defaultLineWidth) {
    toolConfigs.defaultLineWidth = toolConfigs.lineWidth ? toolConfigs.lineWidth[0] : defaultStyle.lineWidth[0]
  }
  if (!toolConfigs.defaultFontSize) {
    toolConfigs.defaultFontSize = toolConfigs.fontSize ? toolConfigs.fontSize[0] : defaultStyle.fontSize[0]
  }

  const assignParams = {
    el,
    configs: Object.assign({}, defaultConfigs, params.configs),
    toolConfigs: Object.assign({}, defaultStyle, toolConfigs)
  }

  delete params.configs
  delete params.toolConfigs

  this.params = Object.assign(assignParams, params)

  toolConfigs = this.params.toolConfigs

  this.annotationHelp = new Markup.Extensions.PdfAnnotationHelper(el)
  this.selectedAnnotation = {
    id: false
  }
  this.undoArr = []
  this.redoArr = []
  if (this.params.configs.showToolbar) {
    const instance = (this.annotationUi = new _AnnotationConstructor({
      data: {
        selectedAnnotation: this.selectedAnnotation,
        undoArr: this.undoArr,
        redoArr: this.redoArr,
        selectedSize: toolConfigs.defaultFontSize,
        selectedColor: toolConfigs.defaultColor,
        selectedLineWidth: toolConfigs.defaultLineWidth,
        selectedShape: toolConfigs.defaultShape,
        toolConfigs,
        showTools: toolConfigs.showTools ?? true
      }
    }))

    instance.vm = instance.$mount()

    instance.dom = instance.vm.$el

    instance.annotationInstance = this

    el.appendChild(instance.dom)

    const markupNode = instance.dom.querySelector('.ann-markups')

    this.annotationHelp.setDomContainer(markupNode)
  } else {
    this.annotationHelp.setDomContainer(el)
  }

  this.unbindEvents = []

  this.globalEvents()
}

index.prototype.globalEvents = function (params) {
  const resize = () => {
    this.resize()
  }

  window.addEventListener('resize', resize, false)

  this.unbindEvents.push(() => {
    window.removeEventListener('resize', resize, false)
  })
}

// 开始批注 创建svg元素
index.prototype.start = function () {
  const { configs, toolConfigs } = this.params

  this.setAnnotationType(toolConfigs.defaultShape)

  this.setAnnotationColor(toolConfigs.defaultColor)

  this.setAnnotationFontSize(toolConfigs.defaultFontSize)

  this.setAnnotationLineWidth(toolConfigs.defaultLineWidth)

  this.annotationHelp.editAnnotationBegin(configs.absBasePoint, configs.screenBasePoint, configs.zoomFactor)

  this.allShapes = {}

  const _addAnnotation = this.annotationHelp.editor.addAnnotation

  this.annotationHelp.editor.addAnnotation = annotation => {
    _addAnnotation.call(this.annotationHelp.editor, annotation)

    if (this.actionType !== 'control') {
      const annotationInfoList = this.annotationHelp.getAnnotationInfoList()

      const simpleList = []

      annotationInfoList.forEach(item => {
        simpleList.push({
          id: item.id
        })
      })

      // 默认为空
      this.allShapes[annotation.id] = {}

      this.undoArr.push(simpleList)
    }
  }

  const _removeAnnotation = this.annotationHelp.editor.removeAnnotation

  this.annotationHelp.editor.removeAnnotation = annotation => {
    const isText = annotation instanceof Markup.Extensions.AnnotationText
    const isControl = (isText && annotation.currText !== '') || !isText

    let simpleList = false

    if (isControl) {
      const annotationInfoList = this.annotationHelp.getAnnotationInfoList()
      simpleList = []

      // 删除前位置信息更新
      annotationInfoList.forEach(item => {
        if (annotation.id !== item.id) {
          simpleList.push({
            id: item.id
          })
        }

        this.allShapes[item.id] = item
      })
    }

    // 删除空text
    if (isText && annotation?.currText?.trim() === '') {
      this.undoArr.pop()
    }

    _removeAnnotation.call(this.annotationHelp.editor, annotation)

    if (this.actionType !== 'control' && isControl) {
      simpleList && this.undoArr.push(simpleList)
    }
  }

  const _setAnnotation = this.annotationHelp.editor.annotationFrame.setAnnotation

  this.annotationHelp.editor.annotationFrame.setAnnotation = annotation => {
    _setAnnotation.call(this.annotationHelp.editor.annotationFrame, annotation)

    if (annotation) {
      this.selectedAnnotation.id = annotation.id
    } else {
      this.selectedAnnotation.id = false
    }
  }

  //  const _deselectAnnotation = this.annotationHelp.editor.deselectAnnotation;
  //  this.annotationHelp.editor.deselectAnnotation = () => {
  //     _deselectAnnotation.call(this.annotationHelp.editor);
  //     console.log(333);
  //  }

  if (this.params.annotations) {
    this._restore({
      annotations: this.params.annotations
    })
  }
}

// 批注 图形
index.prototype.setAnnotationType = function (type) {
  const value = shapeKey[type]
  this.annotationHelp.setAnnotationType(value)
}

// 颜色设置
index.prototype.setAnnotationColor = function (color) {
  this.setAnnotationStyle({
    'stroke-color': color
  })
}

// 颜色设置
index.prototype.setAnnotationFontSize = function (color) {
  this.setAnnotationStyle({
    'font-size': color
  })
}

// 颜色设置
index.prototype.setAnnotationLineWidth = function (color) {
  this.setAnnotationStyle({
    'stroke-width': color
  })
}

// 批注 样式
index.prototype.setAnnotationStyle = function (params) {
  const styleObj = this.params.toolConfigs.style

  const newStyle = Object.assign(styleObj, params)

  this.annotationHelp.setAnnotationStyle(newStyle)
}

// 删除选中批注图形
index.prototype.deleteSelectedAnnotation = function () {
  if (this.annotationHelp.editor.selectedAnnotation) {
    this.annotationHelp.editor.selectedAnnotation.delete()
    this.annotationHelp.editor.selectedAnnotation = null
    this.annotationHelp.editor.deselectAnnotation()
  }
}

// 撤销
index.prototype.undo = function () {
  if (this.undoArr.length < 1) {
    return
  }

  const annotationInfoList = this.annotationHelp.getAnnotationInfoList()

  annotationInfoList.forEach(item => {
    // 更新位置信息
    this.allShapes[item.id] = item
  })

  this.actionType = 'control'

  const redoItem = this.undoArr.pop()
  this.redoArr.push(redoItem)
  const current = this.undoArr[this.undoArr.length - 1] || []

  const loadList = []
  current.forEach(item => {
    loadList.push(this.allShapes[item.id])
  })

  this.annotationHelp.loadAnnotations(loadList)

  this.actionType = 'none'
}
// 恢复
index.prototype.redo = function () {
  if (this.redoArr.length < 1) {
    return
  }

  this.actionType = 'control'

  const current = this.redoArr.pop()

  this.undoArr.push(current)

  const loadList = []
  current.forEach(item => {
    loadList.push(this.allShapes[item.id])
  })

  this.annotationHelp.loadAnnotations(loadList)

  this.actionType = 'none'
}

// 清空
index.prototype.cleanAnnotation = function () {
  this.actionType = 'control'
  this._restore()
  this.undoArr.push([])

  this.actionType = 'none'
}

// 加载批注
index.prototype.loadAnnotations = function (params) {
  this.actionType = 'control'

  this._restore(params)

  const annotationInfoList = this.annotationHelp.getAnnotationInfoList()

  const simpleList = []

  annotationInfoList.forEach(item => {
    simpleList.push({
      id: item.id
    })
  })

  this.undoArr.push(simpleList)

  this.actionType = 'none'
}

index.prototype.hideToolbar = function () {
  this.annotationUi.toolbarStatus(false)
}

// 回看
index.prototype._restore = function (params) {
  if (!params) {
    params = {
      annotations: []
    }
  }

  if (params.length) {
    params = {
      annotations: params
    }
  }

  params = Object.assign(params, this.params.configs)

  if (!params.annotations) {
    params.annotations = []
    console.error('回看批注为空')
  }

  this.annotationHelp.loadAnnotations(
    params.annotations,
    params.absBasePoint,
    params.screenBasePoint,
    params.zoomFactor
  )
}

// 销毁
index.prototype.destroy = function () {
  this.annotationUi.$destroy()
  this.params.el.removeChild(this.annotationUi.vm.$el)
  this.annotationHelp.destroy()
  this.unbindEvents.forEach(fn => fn())
}

// 取消批注
index.prototype.cancel = function () {
  const callback = this.params.cancel
  callback && callback()
  this.destroy()
}

index.prototype.save = function () {
  const callback = this.params.save
  this.params.beforeSave && this.params.beforeSave()
  this.getAnnotationData()
    .then(data => {
      callback && callback(data)
      return false
    })
    .catch(err => {
      console.log(err)
    })
}

index.prototype.getAnnotationData = function (boundary) {
  let _resolve
  // eslint-disable-next-line @typescript-eslint/no-this-alias
  const that = this
  const promise = new Promise(resolve => {
    _resolve = resolve
  })

  let bgImg = null

  const bgImgFn = this.params.setBgImg
  let sizeConfig = this.params.sizeConfig

  if (bgImgFn) bgImg = bgImgFn()

  let imageBorder = 10

  let annotationInfo = this.annotationHelp.getAnnotationInfoListWithBox()

  if (!annotationInfo) {
    const getRect = this.params.getRect

    const annotationNode = document.querySelector('.ann-annotation')

    let defaultBoundingBox = {
      min: {
        x: 0,
        y: 0
      },
      max: {
        x: annotationNode.clientWidth,
        y: annotationNode.clientHeight
      }
    }

    if (getRect) {
      defaultBoundingBox = getRect()
      imageBorder = 0
    }

    annotationInfo = {
      boundingBox: defaultBoundingBox
    }
  }

  const boundingBox = annotationInfo.boundingBox

  if (!boundingBox) {
    // 点击保存后 在进行批注
    const lastAnnotationInfo = that.annotationHelp.getAnnotationInfoListWithBox()
    _resolve({
      annotations: lastAnnotationInfo && lastAnnotationInfo.annotations,
      annotationImage: null
    })
    return promise
  }

  let annotationImage

  if (bgImg) {
    if (bgImg.then) {
      bgImg
        .then(res => {
          bgImg = res // 这里的res是整个图层全部的大小
          mergeBg()
          return false
        })
        .catch(err => {
          console.log(err)
        })
    } else {
      mergeBg()
    }

    function mergeBg() {
      that.annotationHelp.captureAnnotationsScreenSnapshot(bgImg, img => {
        annotationImage = img
        clipImage()
      })
    }
  } else {
    annotationImage = that.annotationHelp.captureAnnotationsScreenSnapshot()
    clipImage()
  }

  function clipImage() {
    const defaultConfig = {
      imageBorder,
      defaultWidth: 400,
      defaultHeight: 260
    }

    if (!sizeConfig) {
      sizeConfig = {}
    }

    sizeConfig = Object.assign(defaultConfig, sizeConfig)

    that.annotationHelp
      .clipImage(annotationImage, boundingBox, sizeConfig, boundary)
      .then(res => {
        // 点击保存后 在进行批注
        const lastAnnotationInfo = that.annotationHelp.getAnnotationInfoListWithBox()
        _resolve({
          annotations: lastAnnotationInfo && lastAnnotationInfo.annotations,
          annotationImage: res
        })
        return false
      })
      .catch(err => {
        console.log(err)
      })
  }

  return promise
}

index.prototype.getSaveData = async function (boundary) {
  const data = await this.getAnnotationData(boundary)
  return {
    base64: data.annotationImage.clipImg64.substr(22),
    originBase64: data.annotationImage.clipImg64,
    xdata: { version: '1.0', annotations: data.annotations }
  }
}

// 窗口大小改变
index.prototype.resize = function (params) {
  if (params) {
    params = Object.assign({}, this.params.configs, params)
    this.annotationHelp.setAbsoluteBasePoint(params.absBasePoint)
    this.annotationHelp.setScreenBasePoint(params.screenBasePoint)
    this.annotationHelp.setZoomFactor(params.zoomFactor.x, params.zoomFactor.y)
  }

  this.annotationHelp.resizeAnnotations()
}

const annotationHelp = {
  /** 剪切图片 */
  clipImage(baseImage, boundingBox, configs) {
    const { imageBorder, defaultWidth, defaultHeight } = configs

    return new Promise(resolve => {
      const tempImgToCut = new Image()
      const sourceBase64 = baseImage
      tempImgToCut.src = sourceBase64

      tempImgToCut.onload = function () {
        let left = boundingBox.min.x - imageBorder

        let canvasWidth = boundingBox.max.x - left + imageBorder

        const imgWidth = tempImgToCut.width

        // 默认留10像素 如果超界了 最大
        if (left + canvasWidth > imgWidth) {
          const gapWidth = imgWidth - left - canvasWidth
          canvasWidth -= gapWidth
        }

        if (canvasWidth < defaultWidth) {
          if (imgWidth < defaultWidth) {
            left = 0
            canvasWidth = defaultWidth
          } else {
            // 需要宽度
            const needWidth = defaultWidth - canvasWidth
            // 剩余宽度
            const restWidth = imgWidth - left - canvasWidth

            if (restWidth < needWidth) {
              canvasWidth += restWidth

              left -= needWidth - restWidth
            } else {
              const gapWidth = defaultWidth - canvasWidth
              canvasWidth = defaultWidth
              left -= gapWidth / 2
            }
          }

          if (left < 0) {
            left = 0
          }
        }

        let top = boundingBox.min.y - imageBorder

        let canvasHeight = boundingBox.max.y - top + imageBorder

        const imgHeight = tempImgToCut.height

        // 默认留10像素 如果超界了 最大
        if (top + canvasHeight > imgHeight) {
          const gapHeight = imgHeight - canvasHeight - top
          canvasHeight -= gapHeight
        }

        if (canvasHeight < defaultHeight) {
          if (imgHeight < defaultHeight) {
            top = 0
            canvasHeight = imgHeight
          } else {
            // 需要宽度
            const needHeight = defaultHeight - canvasWidth
            // 剩余宽度
            const restHeight = imgHeight - top - canvasHeight

            if (restHeight < needHeight) {
              canvasHeight += restHeight

              top -= needHeight - restHeight
            } else {
              const gapHeight = defaultHeight - canvasHeight
              canvasHeight = defaultHeight
              top -= gapHeight / 2
            }
          }

          if (top < 0) {
            top = 0
          }
        }

        const cropCanvas = document.createElement('canvas')
        cropCanvas.width = canvasWidth
        cropCanvas.height = canvasHeight

        cropCanvas
          .getContext('2d')
          .drawImage(tempImgToCut, left, top, canvasWidth, canvasHeight, 0, 0, canvasWidth, canvasHeight)

        const imageData = cropCanvas.getContext('2d').getImageData(0, 0, cropCanvas.width, cropCanvas.height)
        for (let i = 0; i < imageData.data.length; i += 4) {
          // 当该像素是透明的，则设置成白色
          if (imageData.data[i + 3] === 0) {
            imageData.data[i] = 255
            imageData.data[i + 1] = 255
            imageData.data[i + 2] = 255
            imageData.data[i + 3] = 255
          }
        }
        cropCanvas.getContext('2d').putImageData(imageData, 0, 0)
        // console.log(cropCanvas.toDataURL("image/png"));
        resolve({
          clipImg64: cropCanvas.toDataURL('image/png'),
          sourceBase64
        })
      }
    })
  }
}

export default index
